// filesys.h 
//	Data structures to represent the Nachos file system.
//
//	A file system is a set of files stored on disk, organized
//	into directories.  Operations on the file system have to
//	do with "naming" -- creating, opening, and deleting files,
//	given a textual file name.  Operations on an individual
//	"open" file (read, write, close) are to be found in the OpenFile
//	class (openfile.h).
//
//	We define two separate implementations of the file system. 
//	The "STUB" version just re-defines the Nachos file system 
//	operations as operations on the native UNIX file system on the machine
//	running the Nachos simulation.
//
//	The other version is a "real" file system, built on top of 
//	a disk simulator.  The disk is simulated using the native UNIX 
//	file system (in a file named "DISK"). 
//
//	In the "real" implementation, there are two key data structures used 
//	in the file system.  There is a single "root" directory, listing
//	all of the files in the file system; unlike UNIX, the baseline
//	system does not provide a hierarchical directory structure.  
//	In addition, there is a bitmap for allocating
//	disk sectors.  Both the root directory and the bitmap are themselves
//	stored as files in the Nachos file system -- this causes an interesting
//	bootstrap problem when the simulated disk is initialized. 
//
// Copyright (c) 1992-1993 The Regents of the University of California.
// All rights reserved.  See copyright.h for copyright notice and limitation 
// of liability and disclaimer of warranty provisions.

#ifndef FS_H
#define FS_H

#include "copyright.h"
#include "sysdep.h"
#include "openfile.h"
#include "directory.h"
#include <list>
#include <string>

//template <typename T>
//class List;

#ifdef FILESYS_STUB 		// Temporarily implement file system calls as 
				// calls to UNIX, until the real file system
				// implementation is available
class FileSystem {
  public:
    FileSystem() {}

    bool Create(char *name) {
	int fileDescriptor = OpenForWrite(name);

	if (fileDescriptor == -1) return FALSE;
	Close(fileDescriptor); 
	return TRUE; 
	}

    OpenFile* Open(char *name) {
	  int fileDescriptor = OpenForReadWrite(name, FALSE);

	  if (fileDescriptor == -1) return NULL;
	  return new OpenFile(fileDescriptor);
      }

    bool Remove(char *name) { return Unlink(name) == 0; }

};

#else // FILESYS

 
class FileSystem {
  public:
    FileSystem(bool format);		// Initialize the file system.
					// Must be called *after* "synchDisk" 
					// has been initialized.
    					// If "format", there is nothing on
					// the disk, so initialize the directory
    					// and the bitmap of free blocks.

    ~FileSystem();		// Destruct the file system.

    void Install();                    // Install the file system

    bool Create( char *path, char *name );
    bool Create(OpenFile* D_directoryFile, char *name, int initialSize);  	
					// Create a file (UNIX creat)
    bool MakeDir( char *path, char *name/* , int entryCount */);
                                        // Create a directory

    OpenFile* OpenDir( const char *path );     // Open a directory according to the path
                                    
    bool ChDir( char *name );       // Change to a sub directory

    void GetCurWkDir( std::string& path );
                                    // Get the current working directory
    
    OpenFile* Open(char *name); 	// Open a file (UNIX open)

    OpenFile* Open(OpenFile* D_directoryFile, char* name);      //open a file in directory "D_directory"
    
    int Remove( char* path, char *name, bool isDir = false, bool isResv = false );

    /* begin: added by chenshuanglin at seedclass */
    bool Rename(char* path, char *name, char *newname);      //rename a file
    bool Copy(char* S_Path,char * S_Name,char* D_Path,char * D_Name);     //copy a file "S_Name" to the file "D_Name"
    bool Append(char* S_Path,char * S_Name,char* D_Path,char * D_Name);        //append a file to the end of another file
    /* end : added by chenshuanglin at seedclass */
    
    void List();			// List all the files in the file system

    void Print();			// List all the files and their contents

    bool GetDirEnts( char* path, DirectoryEntry * ents, int & cnt );
                            // Get all the directory entries of 
                            // the path.

    bool List( std::string &  path, bool recv );

    bool CatFile( char * path, char * name );

    bool GetFile( char* fromPath, char* toPath, char* toName);

  private:

   void SplitePath( char * szPath, char * szName );

   bool FetchPath( const char* szPath, 
                   std::list<std::string>& lstCurPath );
                                // translate the name to a full path

   OpenFile* freeMapFile;		// Bit map of free disk blocks,
					// represented as a file
   OpenFile* rootDirFile;		// "Root" directory -- list of 
					// file names, represented as a file
   
   std::list<std::string>* lstWorkPath; // list of file names of the working path
   
};

#endif // FILESYS

#endif // FS_H
